package com.gitee.wsl.mathematics.geometry.d3.ext

import com.gitee.wsl.math.Math.sqr
import com.gitee.wsl.mathematics.coordinate.d3.Coordinate3D
import com.gitee.wsl.mathematics.vector.vec3.MutableVec3
import kotlin.math.sqrt

// when this == 0.0 -> result is a
// when this == 1.0 -> result is b
fun Double.atSegmentTo(dest: MutableVec3, a: Coordinate3D<*>, b: Coordinate3D<*>): MutableVec3 { // a + this * (b - a)
    val f = this
    dest.set(a.x + f * (b.x - a.x), a.y + f * (b.y - a.y), a.z + f * (b.z - a.z))
    return dest
}

// when this == 0.0 -> result is a
// when this == 1.0 -> result is b
fun Double.atSegment(a: Coordinate3D<*>, b: Coordinate3D<*>): MutableVec3 = // a + this * (b - a)
    atSegmentTo(MutableVec3(), a, b)

// when this == 0.0 -> result is a.norm
// when this == 1.0 -> result is b.norm
fun Double.distanceAtSegment(a: Coordinate3D<*>, b: Coordinate3D<*>): Double { // norm(a + this * (b - a))
    val f = this
    return norm(a.x + f * (b.x - a.x), a.y + f * (b.y - a.y), a.z + f * (b.z - a.z))
}

internal fun norm(x: Double, y: Double, z: Double): Double =
    sqrt(sqr(x) + sqr(y) + sqr(z))

internal fun norm(x: Float, y: Float, z: Float): Float =
    sqrt(sqr(x) + sqr(y) + sqr(z))